package com.imut.lagain.controller;

import com.imut.lagain.config.FileUploadConfig;
import com.imut.lagain.util.JwtUtil;
import com.imut.lagain.util.ValidationUtil;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
import org.springframework.util.StringUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import jakarta.validation.constraints.*;
import jakarta.validation.Valid;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

/**
 * 文件上传控制器
 */
@RestController
@RequestMapping("/fileupload")
@RequiredArgsConstructor
@Validated
public class FileUploadController {
    private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(FileUploadController.class);

    
    
    private final FileUploadConfig fileUploadConfig;
    private final JwtUtil jwtUtil;
    private static final Map<String, String> ALLOWED_TYPES = new HashMap<>();
    static {
        ALLOWED_TYPES.put("image/jpeg", "images");
        ALLOWED_TYPES.put("image/jpg", "images");
        ALLOWED_TYPES.put("image/png", "images");
        ALLOWED_TYPES.put("image/gif", "images");
        ALLOWED_TYPES.put("image/webp", "images");
        ALLOWED_TYPES.put("audio/mpeg", "audio");
        ALLOWED_TYPES.put("audio/mp3", "audio");
        ALLOWED_TYPES.put("audio/wav", "audio");
        ALLOWED_TYPES.put("audio/ogg", "audio");
        ALLOWED_TYPES.put("audio/aac", "audio");
        ALLOWED_TYPES.put("audio/m4a", "audio");
        ALLOWED_TYPES.put("video/mp4", "video");
        ALLOWED_TYPES.put("video/avi", "video");
        ALLOWED_TYPES.put("video/mov", "video");
        ALLOWED_TYPES.put("video/wmv", "video");
        ALLOWED_TYPES.put("video/flv", "video");
        ALLOWED_TYPES.put("video/webm", "video");
        ALLOWED_TYPES.put("application/pdf", "documents");
        ALLOWED_TYPES.put("application/msword", "documents");
        ALLOWED_TYPES.put("application/vnd.openxmlformats-officedocument.wordprocessingml.document", "documents");
        ALLOWED_TYPES.put("text/plain", "documents");
    }
    
    /**
     * 上传单个文件
     */
    @PostMapping("/upload")
    public ResponseEntity<?> uploadFile(
            @RequestParam("file") @NotNull MultipartFile file,
            @RequestParam(value = "type", required = false) @Pattern(regexp = "^(images|audio|video|documents)$") String type,
            HttpServletRequest request) {
        
        try {
            Long userId = getUserIdFromRequest(request);
            if (userId == null) {
                return ResponseEntity.status(401).body(Map.of("error", "未授权访问"));
            }
            String validationError = validateFile(file);
            if (validationError != null) {
                return ResponseEntity.badRequest().body(Map.of("error", validationError));
            }
            String filePath = saveFile(file, type, userId);
            Map<String, Object> result = new HashMap<>();
            result.put("success", true);
            result.put("fileName", file.getOriginalFilename());
            result.put("filePath", filePath);
            result.put("fileSize", file.getSize());
            result.put("contentType", file.getContentType());
            result.put("uploadTime", LocalDateTime.now());
            
            return ResponseEntity.ok(result);
            
        } catch (Exception e) {
            log.error("File upload failed: {}", e.getMessage(), e);
            return ResponseEntity.status(500).body(Map.of("error", "文件上传失败: " + e.getMessage()));
        }
    }
    
    /**
     * 批量上传文件
     */
    @PostMapping("/upload/batch")
    public ResponseEntity<?> uploadFiles(
            @RequestParam("files") @NotNull @Size(min = 1, max = 10) MultipartFile[] files,
            @RequestParam(value = "type", required = false) @Pattern(regexp = "^(images|audio|video|documents)$") String type,
            HttpServletRequest request) {
        
        try {
            Long userId = getUserIdFromRequest(request);
            if (userId == null) {
                return ResponseEntity.status(401).body(Map.of("error", "未授权访问"));
            }
            
            if (files == null || files.length == 0) {
                return ResponseEntity.badRequest().body(Map.of("error", "请选择要上传的文件"));
            }
            
            if (files.length > 10) {
                return ResponseEntity.badRequest().body(Map.of("error", "一次最多只能上传10个文件"));
            }
            
            List<Map<String, Object>> results = new ArrayList<>();
            List<String> errors = new ArrayList<>();
            
            for (MultipartFile file : files) {
                try {
                    String validationError = validateFile(file);
                    if (validationError != null) {
                        errors.add(file.getOriginalFilename() + ": " + validationError);
                        continue;
                    }
                    String filePath = saveFile(file, type, userId);
                    Map<String, Object> result = new HashMap<>();
                    result.put("fileName", file.getOriginalFilename());
                    result.put("filePath", filePath);
                    result.put("fileSize", file.getSize());
                    result.put("contentType", file.getContentType());
                    
                    results.add(result);
                    
                } catch (Exception e) {
                    log.error("Failed to upload file {}: {}", file.getOriginalFilename(), e.getMessage());
                    errors.add(file.getOriginalFilename() + ": " + e.getMessage());
                }
            }
            
            Map<String, Object> response = new HashMap<>();
            response.put("success", true);
            response.put("uploadedFiles", results);
            response.put("uploadTime", LocalDateTime.now());
            
            if (!errors.isEmpty()) {
                response.put("errors", errors);
            }
            
            return ResponseEntity.ok(response);
            
        } catch (Exception e) {
            log.error("Batch file upload failed: {}", e.getMessage(), e);
            return ResponseEntity.status(500).body(Map.of("error", "批量文件上传失败: " + e.getMessage()));
        }
    }
    
    /**
     * 删除文件
     */
    @DeleteMapping("/delete")
    public ResponseEntity<?> deleteFile(
            @RequestParam("filePath") @NotBlank @Size(max = 500) String filePath,
            HttpServletRequest request) {
        
        try {
            Long userId = getUserIdFromRequest(request);
            if (userId == null) {
                return ResponseEntity.status(401).body(Map.of("error", "未授权访问"));
            }
            Path fullPath = Paths.get(fileUploadConfig.getUploadPath(), filePath);
            if (!fullPath.startsWith(fileUploadConfig.getUploadPath())) {
                return ResponseEntity.badRequest().body(Map.of("error", "非法的文件路径"));
            }
            if (Files.exists(fullPath)) {
                Files.delete(fullPath);
                return ResponseEntity.ok(Map.of("success", true, "message", "文件删除成功"));
            } else {
                return ResponseEntity.badRequest().body(Map.of("error", "文件不存在"));
            }
            
        } catch (Exception e) {
            log.error("File deletion failed: {}", e.getMessage(), e);
            return ResponseEntity.status(500).body(Map.of("error", "文件删除失败: " + e.getMessage()));
        }
    }
    
    /**
     * 验证文件
     */
    private String validateFile(MultipartFile file) {
        if (file == null || file.isEmpty()) {
            return "请选择要上传的文件";
        }
        String originalFilename = file.getOriginalFilename();
        if (!StringUtils.hasText(originalFilename)) {
            return "文件名不能为空";
        }
        if (file.getSize() > 50 * 1024 * 1024) {
            return "文件大小不能超过50MB";
        }
        String contentType = file.getContentType();
        if (!StringUtils.hasText(contentType) || !ALLOWED_TYPES.containsKey(contentType)) {
            return "不支持的文件类型: " + contentType;
        }
        String extension = getFileExtension(originalFilename);
        if (!isValidExtension(extension, contentType)) {
            return "文件扩展名与文件类型不匹配";
        }
        
        return null;
    }
    
    /**
     * 保存文件
     */
    private String saveFile(MultipartFile file, String type, Long userId) throws IOException {
        String contentType = file.getContentType();
        String subDir = StringUtils.hasText(type) ? type : ALLOWED_TYPES.get(contentType);
        String originalFilename = file.getOriginalFilename();
        String extension = getFileExtension(originalFilename);
        String timestamp = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMdd_HHmmss"));
        String uniqueId = UUID.randomUUID().toString().substring(0, 8);
        String newFileName = String.format("%s_%d_%s%s", timestamp, userId, uniqueId, extension);
        Path uploadDir = Paths.get(fileUploadConfig.getUploadPath(), subDir);
        if (!Files.exists(uploadDir)) {
            Files.createDirectories(uploadDir);
        }
        
        Path filePath = uploadDir.resolve(newFileName);
        file.transferTo(filePath.toFile());
        return subDir + "/" + newFileName;
    }
    
    /**
     * 获取文件扩展名
     */
    private String getFileExtension(String filename) {
        if (!StringUtils.hasText(filename)) {
            return "";
        }
        
        int lastDotIndex = filename.lastIndexOf('.');
        if (lastDotIndex > 0 && lastDotIndex < filename.length() - 1) {
            return filename.substring(lastDotIndex);
        }
        
        return "";
    }
    
    /**
     * 验证文件扩展名
     */
    private boolean isValidExtension(String extension, String contentType) {
        if (!StringUtils.hasText(extension)) {
            return false;
        }
        
        extension = extension.toLowerCase();
        
        switch (contentType) {
            case "image/jpeg":
            case "image/jpg":
                return ".jpg".equals(extension) || ".jpeg".equals(extension);
            case "image/png":
                return ".png".equals(extension);
            case "image/gif":
                return ".gif".equals(extension);
            case "image/webp":
                return ".webp".equals(extension);
            case "audio/mpeg":
            case "audio/mp3":
                return ".mp3".equals(extension);
            case "audio/wav":
                return ".wav".equals(extension);
            case "video/mp4":
                return ".mp4".equals(extension);
            case "application/pdf":
                return ".pdf".equals(extension);
            default:
                return true; // 其他类型暂时允许
        }
    }
    
    /**
     * 从请求中获取用户ID
     */
    private Long getUserIdFromRequest(HttpServletRequest request) {
        try {
            Object userIdAttr = request.getAttribute("userId");
            if (userIdAttr instanceof Long) {
                return (Long) userIdAttr;
            }
            String authHeader = request.getHeader("Authorization");
            if (StringUtils.hasText(authHeader) && authHeader.startsWith("Bearer ")) {
                String token = authHeader.substring(7);
                if (jwtUtil.validateToken(token)) {
                    return jwtUtil.getUserIdFromToken(token);
                }
            }
        } catch (Exception e) {
            log.debug("Failed to get user ID from request: {}", e.getMessage());
        }
        
        return null;
    }
}

